package com.tenement.utils;

import com.alibaba.fastjson.JSON;
import lombok.RequiredArgsConstructor;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;

import java.util.concurrent.TimeUnit;

@Component
@RequiredArgsConstructor
public class RedisCache {

    private final StringRedisTemplate redisTemplate;


    public void setValue(String key, Object value)
    {
        redisTemplate.opsForValue().set(key, JSON.toJSONString(value));
    }

    /**
     * 将给定的键值对存储到Redis中，并设定过期时间。
     *
     * @param key 键，用于标识存储的数据。
     * @param value 值，需要存储的数据，支持多种数据类型，这里通过JSON.toJSONString转换为字符串形式存储。
     * @param timeout 过期时间的长度。
     * @param timeUnit 过期时间的单位。
     */
    public void setValue(String key, Object value, long timeout, TimeUnit timeUnit)
    {
        // 使用RedisTemplate的opsForValue方法设置键值对，并设定过期时间
        redisTemplate.opsForValue().set(key, JSON.toJSONString(value), timeout, timeUnit);
    }


    /**
     * 从Redis中获取指定key的值，并将其转换为指定类型T。
     *
     * @param key 要获取值的Redis键。
     * @param clazz 指定转换后的类型T。
     * @return 转换后的对象T，如果key不存在或转换失败，则返回null。
     */
    public <T> T getValue(String key, Class<T> clazz)
    {
        // 从Redis获取key对应的值，然后将其解析为clazz指定的类型
        return JSON.parseObject(redisTemplate.opsForValue().get(key),clazz);
    }



    /**
     * 从Redis中删除指定的键值。
     *
     * @param key 要删除的键，不能为空。
     * @return 删除操作是否成功。如果删除成功，返回true；否则返回false。
     */
    public boolean delete(String key) {
        // 使用redisTemplate删除指定的键，并将结果转换为Boolean类型进行判断
        return Boolean.TRUE.equals(redisTemplate.delete(key));
    }


    public boolean hasKey(String key) {
        return Boolean.TRUE.equals(redisTemplate.hasKey(key));
    }

    public void setExpire(String key, long timeout, TimeUnit unit) {
        redisTemplate.expire(key, timeout, unit);
    }

    public Long getExpire(String key) {
        return redisTemplate.getExpire(key);
    }

    public void setSetVal(String key, Object value) {
        redisTemplate.opsForSet().add(key,value.toString());
    }

    public boolean isMember(String key, Object value)
    {
        if (!hasKey(key)) {
            return false;
        }
        return Boolean.TRUE.equals(redisTemplate.opsForSet().isMember(key, value.toString()));
    }

    public String getSetPopVal(String key) {
        return redisTemplate.opsForSet().pop(key);
    }


    public Long getSetSize(String key) {
        return redisTemplate.opsForSet().size(key);
    }


    public Long setIncrement(String key, long step) {
        return redisTemplate.opsForValue().increment(key, step);
    }

    public long getIncrementVal(String key) {
        String res = redisTemplate.opsForValue().get(key);
        return res != null ? Long.parseLong(res) : 0L;
    }

    public void setHashVal(String key, String field, Object value) {
        redisTemplate.opsForHash().put(key, field, value);
    }


    public void setLogVal(String key, Object value) {
        redisTemplate.opsForHyperLogLog().add(key, value.toString());
    }

    public Long getLogSize(String key) {
        return redisTemplate.opsForHyperLogLog().size(key);
    }


}
